#ifndef __RAYTRACER_IMAGE_FACTORY_H__
#define __RAYTRACER_IMAGE_FACTORY_H__

#include "singleton.h"
#include "image.h"

namespace raytracer {

class ImageFactory :
   public Singleton<ImageFactory>
{
   SINGLETON_ONLYDEF(ImageFactory);

private:

   GFL_BITMAP * m_data;
   GFL_FILE_INFORMATION m_info;
public:
   GFL_INT32 mGetFormatIndex(
      const std::string &a_filename);

   bool mLoadDataBuffer(
      const std::string &a_filename,
      const GFL_BITMAP_TYPE &a_gfl_type);

   bool mSaveDataBuffer(
      const std::string &a_filename);

   void mCreateDataBuffer(
      const size_t &a_width,
      const size_t &a_height,
      const GFL_BITMAP_TYPE &a_gfl_type);

   void mClearDataBuffer();

   template<typename DataType, typename PixelType>
   boost::shared_ptr< Image<DataType,PixelType> > mLoad(
      const std::string &a_filename);

   template<typename DataType, typename PixelType>
   bool mSave(
      const boost::shared_ptr< Image<DataType,PixelType> > &a_image,
      const std::string &a_filename);

   template<typename DataType, typename PixelType>
   boost::shared_ptr< Image<DataType,PixelType> > mCreate(
      const size_t &a_width,
      const size_t &a_height);

   template<typename DataType, typename PixelType>
   boost::shared_ptr< Image<DataType,PixelType> > mCreate();

public:

   template<typename DataType, typename PixelType>
   static boost::shared_ptr< Image<DataType,PixelType> > create(
      const size_t &a_width,
      const size_t &a_height);

   template<typename DataType, typename PixelType>
   static boost::shared_ptr< Image<DataType,PixelType> > create();

   template<typename DataType, typename PixelType>
   static boost::shared_ptr< Image<DataType,PixelType> > create(
      const std::string &a_filename);

   template<typename DataType, typename PixelType>
   static bool save(
      const boost::shared_ptr< Image<DataType, PixelType> > &a_image,
      const std::string &a_filename);

   template<typename DataType>
   static boost::shared_ptr< Image<DataType,rgb_t> > create(
      const size_t &a_width,
      const size_t &a_height);

   template<typename DataType>
   static boost::shared_ptr< Image<DataType,rgb_t> > create();

   template<typename DataType>
   static boost::shared_ptr< Image<DataType,rgb_t> > create(
      const std::string &a_filename);

   template<typename DataType>
   static bool save(
      const boost::shared_ptr< Image<DataType,rgb_t> > &a_image,
      const std::string &a_filename);

};

} //end of namespace

#include "imagefactory.hxx"

#endif //__RAYTRACER_IMAGE_FACTORY_H__
